<?php
/**
 * Created by PhpStorm.
 * User: 764432054@qq.com
 * Date: 2020/5/21
 * Time: 0:23
 */


$ip = "0.0.0.0";
$port = $argv[1];
$sockefd = socket_create(AF_INET,SOCK_STREAM,0);
socket_set_option($sockefd,SOL_SOCKET,SO_REUSEPORT,1);
socket_bind($sockefd,$ip,$port);
socket_listen($sockefd,5);


$connectionfds = [];
$readfds = [$sockefd];
$writefds = [$sockefd];
$exceptionfds = [$sockefd];
$bufferMessage = "hello,world".PHP_EOL;
$recvMessage = "";
$remoteIP;
$remoteAddr;

fprintf(STDOUT,"server pid=%d\n",posix_getpid());
$i=0;
while ("server") {

    $read_fds      = $readfds;
    $write_fds     = $writefds;
    $exception_fds = $exceptionfds;


    echo "Before r_fds=".fds($read_fds).""."      w_fds=".fds($write_fds)."      e_fds=".fds($exception_fds).PHP_EOL;

    $connectNum = socket_select($read_fds, $write_fds, $exception_fds, NULL);
    echo "After  r_fds=".fds($read_fds).""."      w_fds=".fds($write_fds)."      e_fds=".fds($exception_fds).PHP_EOL.PHP_EOL;
    if (!$connectNum) {
        break;
    }
    #可读
    foreach ($read_fds as $fd) {

        if ($fd == $sockefd) {
            $connfd = socket_accept($sockefd);
            socket_set_nonblock($connfd);

            socket_getpeername($connfd,$remoteIP,$remoteAddr);
            fprintf(STDOUT, "new connection %s ,ip is %s,port is %d\n", $connfd,$remoteIP,$remoteAddr);
            $readfds[]       = $connfd;
            $exceptionfds[]  = $connfd;
            $connectionfds[] = $connfd;
        } else {

            $recvMessage = socket_read($fd, 8192);

            if (!$recvMessage) {
                socket_close($fd);
                unset($exceptionfds[array_search($fd, $exceptionfds)]);
                unset($writefds[array_search($fd, $writefds)]);
                unset($readfds[array_search($fd, $readfds)]);
            } else {
                if (stripos("QUIT",$recvMessage) !== false){
                    socket_send($fd,"quit\n",6,0);
                    socket_close($fd);
                    unset($exceptionfds[array_search($fd, $exceptionfds)]);
                    unset($writefds[array_search($fd, $writefds)]);
                    unset($readfds[array_search($fd, $readfds)]);
                }else{
                    fprintf(STDOUT, "recv from client msg:%s\n", $recvMessage);
                }

            }

        }
    }

    #写
    foreach ($write_fds as $fd) {
        $writeBytes = socket_write($fd, $bufferMessage, strlen($bufferMessage));
        unset($writefds[array_search($fd, $writefds)]);
        if (!$writeBytes) {
            socket_close($fd);
            unset($readfds[array_search($fd, $readfds)]);
            unset($exceptionfds[array_search($fd, $exceptionfds)]);
        } else {
            array_push($readfds, $fd);
        }
    }

    foreach ($exception_fds as $fd) {
        socket_close($fd);
        unset($readfds[array_search($fd, $readfds)]);
        unset($exceptionfds[array_search($fd, $exceptionfds)]);
        unset($writefds[array_search($fd, $writefds)]);
    }



}
socket_close($sockefd);

function fds($fds){
    $str='';
    foreach ($fds as $fd){
        $str.=intval($fd).",";
    }
    return "[".trim($str,',')."]";
}